Add phx.gen.release task for release/docker based deployments - #4609
Conversation
|
The |
Co-authored-by: Michael Crumm <mike@crumm.net>
Gazler
left a comment
There was a problem hiding this comment.
Good idea, covers most of the common cases. Big +1 for the server: true change.
| For example: ecto://USER:PASS@HOST/DATABASE | ||
| \""" | ||
|
|
||
| ipv6? = System.get_env("IPV6") == "true" |
There was a problem hiding this comment.
Is IPV6 the correct environment variable here? Since this is specific to the db socket, wouldn't something like DATABASE_IPV6 be more appropriate?
| Your application is ready to be deployed in a release! | ||
|
|
||
| # To start your system | ||
| _build/dev/rel/live_beats/bin/live_beats start |
| File.chmod!("rel/overlays/bin/migrate", 0o700) | ||
| File.chmod!("rel/overlays/bin/server", 0o700) | ||
|
|
||
| Mix.shell().info(""" |
There was a problem hiding this comment.
Shouldn't this shell info explain something about building for Docker vs release information from mix?
| ]) | ||
|
|
||
| Mix.Phoenix.copy_from(paths(), "priv/templates/phx.gen.docker/rel", binding, [ | ||
| {:eex, "env.bat.eex", "rel/env.bat.eex"}, |
There was a problem hiding this comment.
Is there a way we could leverage these from the existing mix release.init task to keep any changes in sync with the Elixir version?
There was a problem hiding this comment.
I don't see why we need to generate them. Could we tell them to use mix release.init if necessary?
There was a problem hiding this comment.
Alternatively, we call this mix phx.gen.release and support a --docker flag?
| # - https://pkgs.org/ - resource for finding needed packages | ||
| # - Ex: hexpm/elixir:1.12.3-erlang-24.1.4-debian-bullseye-20210902-slim | ||
| # | ||
| ARG BUILDER_IMAGE="hexpm/elixir:1.12.3-erlang-24.1.4-debian-bullseye-20210902-slim" |
There was a problem hiding this comment.
Should we leverage:
Application.spec(:elixir, :vsn) and :erlang.system_info(:version) (not sure how to get the minor version here)
So that the build image matches the elixir version in use?
This might have a downside as we can't ensure the image exists vs using a hard-coded string.
There was a problem hiding this comment.
Good call. We can do -erlang-24.1-, which perhaps is the safest choice.
| # note: if your project uses a tool like https://purgecss.com/, | ||
| # which customizes asset compilation based on what it finds in | ||
| # your Elixir templates, you will need to move the asset compilation | ||
| # step down so that `lib` is available. | ||
| COPY assets assets |
There was a problem hiding this comment.
Can asset compilation always be after lib? Won't it cover both cases with and without purgecss?
I don't know if there are any downsides of permanently moving it a step down, but this could make the generated dockerfile clearer.
There was a problem hiding this comment.
The downside is slower builds when you change something in lib. This would trigger and asset recompilation.
There's a way to do both with a multistage Dockerfile though, it's a good idea.
| server? = System.get_env("SERVER") == "true" | ||
|
|
||
| config :<%= @app_name %>, <%= @endpoint_module %>, | ||
| url: [host: host, port: 80], |
There was a problem hiding this comment.
Not sure if I am happy with the hardcoded port here. I am wondering if instead we could support url as a string which we will parse. So we could do: url: System.get_env("PHX_URL"), and we set PHX_URL=example.com:80. The code would parse the string and discard all nil fields?
| @doc false | ||
| def run(_args) do | ||
| if Mix.Project.umbrella?() do | ||
| Mix.raise("mix phx.gen.docker is not supported in umbrella applications") |
There was a problem hiding this comment.
Maybe mention they should generate it within their web app instead?
|
Updates:
|
| Mix.shell().info(msg) | ||
| end | ||
| end | ||
| end |
| @@ -0,0 +1,3 @@ | |||
| #!/bin/sh | |||
| cd -P -- "$(dirname -- "$0")" | |||
| PHX_SERVER=true ./<%= otp_app %> start | |||
There was a problem hiding this comment.
Similar here:
| PHX_SERVER=true ./<%= otp_app %> start | |
| exec PHX_SERVER=true ./<%= otp_app %> start |
I don't know if exec should come before or after the env var.
Co-authored-by: José Valim <jose.valim@dashbit.co>
Co-authored-by: José Valim <jose.valim@dashbit.co>
| IO.warn("unable to read OTP minor version at #{path}. Falling back to #{major}.0.0") | ||
| "#{major}.0.0" |
There was a problem hiding this comment.
| IO.warn("unable to read OTP minor version at #{path}. Falling back to #{major}.0.0") | |
| "#{major}.0.0" | |
| IO.warn("unable to read OTP minor version at #{path}. Falling back to #{major}.0") | |
| "#{major}.0" |
| with {:ok, content} <- File.read(path), | ||
| {:ok, %Version{} = vsn} <- Version.parse(String.trim_trailing(content)) do | ||
| "#{vsn.major}.#{vsn.minor}.#{vsn.patch}" |
There was a problem hiding this comment.
OTP versioning is... tricky. There is no 24.1.0, it is just 24.1. But i guess you could do this:
| with {:ok, content} <- File.read(path), | |
| {:ok, %Version{} = vsn} <- Version.parse(String.trim_trailing(content)) do | |
| "#{vsn.major}.#{vsn.minor}.#{vsn.patch}" | |
| with {:ok, content} <- File.read(path) do | |
| String.trim(content) |
Co-authored-by: José Valim <jose.valim@dashbit.co>
Co-authored-by: José Valim <jose.valim@dashbit.co>
Co-authored-by: José Valim <jose.valim@dashbit.co>
I'm not super firm on env names, so would love feedback. The migrate and server shims are necessary for deployments where it's difficult for infrastructure to know what the OTP app name is. If we are happy with this direction, we can add bat scripts for windows to match migrate/server.